package com.lh.common.exception;


import com.lh.common.utils.Constant;
import com.lh.common.utils.Result;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authz.AuthorizationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.io.IOException;
import java.sql.SQLException;

/**
 * 异常处理器
 *
 * @author Mark sunlightcs@gmail.com
 */
@RestControllerAdvice
public class RRExceptionHandler {
	private Logger logger = LoggerFactory.getLogger(getClass());

	/**
	 * 处理自定义异常
	 */
	@ExceptionHandler(RRException.class)
	public Result handleRRException(RRException e){
		return  Result.error(e.getCode(),e.getMessage());
	}

	@ExceptionHandler(NoHandlerFoundException.class)
	public Result handlerNoFoundException(Exception e) {
		logger.error(e.getMessage(), e);
		return Result.error(Constant.RESULT.EX404, "路径不存在，请检查路径是否正确");
	}

	@ExceptionHandler(DuplicateKeyException.class)
	public Result handleDuplicateKeyException(DuplicateKeyException e){
		logger.error(e.getMessage(), e);
		return Result.error(Constant.RESULT.EX9111, "数据库中已存在该记录");
	}

	@ExceptionHandler(AuthorizationException.class)
	public Result handleAuthorizationException(AuthorizationException e){
		//TODO::此类日志不提示，不加入bug计算（测试建议）
//		logger.error(e.getMessage(), e);
		return Result.error(Constant.RESULT.EX9110, "没有权限，请联系管理员授权");
	}

	@ExceptionHandler(Exception.class)
	public Result handleException(Exception e){
		logger.error(e.getMessage(), e);
		return Result.error();
	}

	@ExceptionHandler(IncorrectCredentialsException.class)
	public Result incorrectCredentialsException(IncorrectCredentialsException e){
		logger.error(e.getMessage(), e);
		return Result.error(HttpStatus.UNAUTHORIZED.value(), "token失效，请重新登录");
	}

	@ExceptionHandler(LockedAccountException.class)
	public Result lockedAccountException(LockedAccountException e){
		logger.error(e.getMessage(), e);
		return Result.error(Constant.RESULT.EX9113, "账号已被锁定,请联系管理员");
	}

	//上传文件出现的异常
    @ExceptionHandler(SQLException.class)
    public Result handlerSQLException(SQLException e) {
        logger.error(e.getMessage(), e);
        return Result.error(Constant.RESULT.EX9114, "数据库操作异常");
    }

    @ExceptionHandler(NullPointerException.class)
    public Result nullpointerException(NullPointerException e) {
        logger.error(e.getMessage(), e);
        return Result.error(Constant.RESULT.EX9115, "空指针异常");
    }

    @ExceptionHandler(IOException.class)
    public Result ioException(IOException e) {
        logger.error(e.getMessage(), e);
        return Result.error(Constant.RESULT.EX9116, "文件操作异常");
    }

    /**
     * 校验入参异常
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result processMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        FieldError fieldError = e.getBindingResult().getFieldError();
        assert fieldError != null;
        logger.error(fieldError.getField() + ":" + fieldError.getDefaultMessage());
        return Result.error(Constant.RESULT.FI1000, fieldError.getDefaultMessage());
    }
}
